/**
 * 
 */
package wong.board.client.ui;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import wong.board.client.ui.DevelopmentPresenter.View;
import wong.board.client.util.JSONTool;
import wong.board.client.widgets.Button;
import wong.board.client.widgets.ButtonsContainer;
import wong.board.client.widgets.Container;
import wong.board.client.widgets.ContentContainer;
import wong.board.client.widgets.HasButtonCallbacks;
import wong.board.client.widgets.Input;
import wong.board.client.widgets.ToggleButton;
import wong.board.shared.ContentKeys;

import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HasText;
import com.google.gwt.user.client.ui.HasValue;

/**
 * @author wong
 * 
 */
public class DevelopmentView extends ContentContainer implements View {
	private static final String ID_LIST_HOST = "hostList";
	private static final String ID_LIST_PORT = "portList";

	private ToggleButton sameWindow;
	private ToggleButton useHttps;
	private Input hostName;
	// private DataList portList;
	private Input port;
	private FlowPanel items;
	private ButtonsContainer<JSONArray> buttons;
	private ArrayList<ParameterView> parameterViews;

	public DevelopmentView() {
		super(ContentKeys.Development.toString());

		sameWindow = new ToggleButton("same window");
		sameWindow.addStyleName(boardCss.developmentItem());

		useHttps = new ToggleButton("use https");
		useHttps.addStyleName(boardCss.developmentItem());

		hostName = new Input();
		hostName.addStyleName(boardCss.developmentItem());
		hostName.setPlaceholder("hostname");
		hostName.setList(ID_LIST_HOST);
		hostName.setSize(15);

		// portList = new DataList();

		port = new Input();
		port.addStyleName(boardCss.developmentItem());
		port.setPlaceholder("port");
		port.setList(ID_LIST_PORT);
		port.setSize(5);

		items = new FlowPanel();
		items.setStyleName(boardCss.developmentItems());
		items.add(sameWindow);
		items.add(useHttps);
		items.add(hostName.getDataList());
		items.add(hostName);
		items.add(port.getDataList());
		items.add(port);

		buttons = new ButtonsContainer<JSONArray>();
		buttons.addStyleName(boardCss.developmentButtons());

		getContent().add(items);
		getContent().add(buttons);

		addStyleName(boardCss.development());
	}

	@Override
	public HasValue<Boolean> getSameWindow() {
		return sameWindow;
	}

	@Override
	public HasValue<Boolean> getUseHttps() {
		return useHttps;
	}

	@Override
	public HasText getHostName() {
		return hostName;
	}

	@Override
	public void setHostList(JSONObject hostList) {
		this.hostName.getDataList().setData(hostList);
	}

	@Override
	public HasText getPort() {
		return port;
	}

	@Override
	public void setPortList(JSONObject portList) {
		this.port.getDataList().setData(portList);
	}

	@Override
	public void resetButtons() {
		buttons.clear();
	}

	@Override
	public void addButton(JSONArray buttonData) {
		String text = buttonData.get(0).isString().stringValue();
		String title = buttonData.get(1).isString().stringValue();
		Button<JSONArray> button = new Button<JSONArray>(buttonData, text);
		button.setTitle(title);
		button.addStyleName(boardCss.developmentButton());
		buttons.addButton(button);
	}

	@Override
	public void addParameter(String id, String name, String text, int size, JSONObject data) {
		// ParameterView parameterView = new ParameterView(id, name, text, size,
		// data);
		ParameterView parameterView = getParameterView(name);
		if (parameterView == null) {
			parameterView = new ParameterView(id, name, text, size, data);
			items.add(parameterView);
			parameterViews.add(parameterView);
		} else {
			parameterView.setText(text);
			parameterView.setSize(size);
			JSONObject currentData = parameterView.getData();
			if (currentData == null) {
				currentData = data;
			} else {
				currentData = JSONTool.merge(currentData, data, true);
			}
			parameterView.setData(currentData);
		}

	}

	@Override
	public Map<String, String> getSelectedParameters() {
		HashMap<String, String> params = new HashMap<String, String>();
		if (parameterViews != null) {
			for (ParameterView parameterView : parameterViews) {
				if (parameterView.useButton.getValue().booleanValue()) {
					String name = parameterView.useButton.getText();
					String value = parameterView.parameterValue.getText();
					params.put(name, value);
				}
			}
		}
		return params;
	}

	@Override
	public HasButtonCallbacks<JSONArray> getLaunchButtonsCallbacks() {
		return buttons;
	}

	private ParameterView getParameterView(String label) {
		if (parameterViews == null) {
			parameterViews = new ArrayList<DevelopmentView.ParameterView>();
		}
		for (ParameterView view : parameterViews) {
			if (view.getLabel().equals(label)) {
				return view;
			}
		}
		return null;
	}

	/*
	 * 
	 */

	private class ParameterView extends Container {
		private final String listId;
		private ToggleButton useButton;
		private Input parameterValue;
		private JSONObject data;

		public ParameterView(String id, String label) {
			this.setStyleName(boardCss.developmentParameter());

			this.getElement().setId(id);
			listId = "list-" + id;
			useButton = new ToggleButton(label);
			parameterValue = new Input();
			parameterValue.setPlaceholder("parameter value");
			parameterValue.setList(listId);

			getContainer().add(parameterValue.getDataList());
			getContainer().add(useButton);
			getContainer().add(parameterValue);
		}

		public ParameterView(String id, String label, String text, int size, JSONObject data) {
			this(id, label);
			setText(text);
			setSize(size);

			setData(data);
		}

		public String getLabel() {
			return useButton.getText();
		}

		public void setText(String newText) {
			parameterValue.setText(newText);
		}

		public void setData(JSONObject newData) {
			parameterValue.getDataList().setData(newData);
			this.data = newData;
		}

		public JSONObject getData() {
			return this.data;
		}

		public void setSize(int newSize) {
			parameterValue.setSize(newSize);
		}
	}

}
